package src.com.susiqi.utils;

import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;
import java.util.Base64;

public class SecurePasswordEncryptor {

    // 安全参数配置
    private static final int ITERATIONS = 10000;       // 迭代次数（增加计算成本）
    private static final int KEY_LENGTH = 256;        // 密钥长度（位）
    private static final int SALT_LENGTH = 16;        // 盐值长度（字节）
    private static final String ALGORITHM = "PBKDF2WithHmacSHA256";

    /**
     * 生成随机盐值
     * @return Base64编码的盐值字符串
     */
    public static String generateSalt() {
        SecureRandom random = new SecureRandom();
        byte[] salt = new byte[SALT_LENGTH];
        random.nextBytes(salt);
        return Base64.getEncoder().encodeToString(salt);
    }

    /**
     * 加密密码
     * @param password 原始密码
     * @param salt 盐值（Base64编码）
     * @return 加密后的密码（Base64编码）
     */
    public static String encrypt(String password, String salt) {
        try {
            byte[] saltBytes = Base64.getDecoder().decode(salt);
            PBEKeySpec spec = new PBEKeySpec(
                    password.toCharArray(),
                    saltBytes,
                    ITERATIONS,
                    KEY_LENGTH
            );

            SecretKeyFactory factory = SecretKeyFactory.getInstance(ALGORITHM);
            byte[] hash = factory.generateSecret(spec).getEncoded();
            return Base64.getEncoder().encodeToString(hash);
        } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
            throw new RuntimeException("密码加密失败", e);
        }
    }

    /**
     * 验证密码
     * @param password 原始密码
     * @param salt 盐值（Base64编码）
     * @param encryptedPassword 加密后的密码（Base64编码）
     * @return 验证结果
     */
    public static boolean verify(String password, String salt, String encryptedPassword) {
        String newEncrypted = encrypt(password, salt);
        return newEncrypted.equals(encryptedPassword);
    }
}

